package cn.stu.cms.config;


import cn.hutool.core.collection.CollUtil;
import cn.stu.cms.util.R;
import lombok.extern.slf4j.Slf4j;
import org.springframework.context.support.DefaultMessageSourceResolvable;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;

import java.time.format.DateTimeParseException;
import java.util.List;
import java.util.stream.Collectors;

import static cn.stu.cms.common.CommonConstants.ERROR_MSG_MAX_COUNT;
import static com.baomidou.mybatisplus.core.toolkit.StringPool.COMMA;

/**
 * 参数异常控制器
 *
 * @author gh
 * @date 2023/09/12
 */
@Slf4j
@RestControllerAdvice
public class ParamExceptionController {


    /**
     * 非法参数异常处理程序
     * 处理断言中抛出的参数异常
     *
     * @param e E
     * @return {@link R}
     */

    @ExceptionHandler(IllegalArgumentException.class)
    public R<String> illegalArgumentExceptionHandler(IllegalArgumentException e) {
        log.error("date param is illegal，message is:{}", e.getMessage());
        return R.failed(e.getMessage());
    }


    /**
     * 日期时间分析异常处理程序
     * 处理时间类型请求参数格式错误 失败后抛出的异常是java.time.format.DateTimeParseException;
     *
     * @param e E
     * @return {@link R}
     */

    @ExceptionHandler(value = DateTimeParseException.class)
    public R<String> dateTimeParseExceptionHandler(DateTimeParseException e) {
        log.error("date param:{} is error，message is:{}", e.getParsedString(), e.getMessage());
        return R.failed("时间参数非法");
    }

    /**
     * 处理有效异常
     * 处理请求参数格式错误 @RequestParam上validate失败后抛出的异常是javax.validation.MethodArgumentNotValidException
     *
     * @param error 异常类
     * @return 响应
     * @Validated @Valid 前端提交的方式为json格式有效
     */

    @ExceptionHandler(value = MethodArgumentNotValidException.class)
    public R<String> handleValidException(MethodArgumentNotValidException error) {
        log.error("数据校验异常{}，异常类型{}", error.getMessage(), error.getClass());
        List<String> collect = error.getBindingResult()
                .getFieldErrors()
                .stream()
                .limit(ERROR_MSG_MAX_COUNT)
                .map(DefaultMessageSourceResolvable::getDefaultMessage)
                .collect(Collectors.toList());
        return R.failed(CollUtil.join(collect, COMMA));
    }
}